package me.xinping.libs.utils

import android.text.TextUtils
import android.util.Log

/**
 * Log Utility for developing. Call these methods instead of using android.util.Log methods.
 * This is convenient for control log output by ourselves.
 */
object LogUtils {
    /**
     * The log tag of app2b client.
     */
    private const val LOG_TAG = "record"

    /**
     * Log in verbose level.
     *
     * @param subTag the sub log tag, could be empty
     * @param msg    log message
     */
    fun i(subTag: String, msg: String) {
        if (Log.isLoggable(LOG_TAG, Log.INFO)) {
            Log.i(LOG_TAG, combineMessage(subTag, msg))
        }
    }

    fun i(clz: Class<*>?, msg: String) {
        val clzName = clz?.simpleName ?: LogUtils::class.java.name
        i(clzName, msg)
    }

    /**
     * Log in debug level.
     *
     * @param subTag the sub log tag, could be empty
     * @param msg    log message
     */
    fun d(subTag: String, msg: String) {
        if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
            Log.d(LOG_TAG, combineMessage(subTag, msg))
        }
    }

    /**
     * Log in error level.
     *
     * @param subTag the sub log tag, could be empty
     * @param msg    log message
     */
    fun e(subTag: String, msg: String) {
        if (Log.isLoggable(LOG_TAG, Log.ERROR)) {
            Log.e(LOG_TAG, combineMessage(subTag, msg))
        }
    }

    /**
     * Log in error level with throwable.
     *
     * @param subTag the sub log tag, could be empty
     * @param msg    log message
     * @param tr     the throwable
     */
    fun e(subTag: String, msg: String, tr: Throwable) {
        if (Log.isLoggable(LOG_TAG, Log.ERROR)) {
            Log.e(LOG_TAG, combineMessage(subTag, msg), tr)
        }
    }

    fun e(clz: Class<*>?, msg: String, tr: Throwable) {
        val clzName = clz?.simpleName ?: LogUtils::class.java.name
        e(clzName, msg, tr)
    }

    private fun combineMessage(subTag: String, msg: String): String {
        return if (!TextUtils.isEmpty(subTag)) {
            "$subTag : $msg"
        } else msg
    }

    /**
     * 打印 INFO 日志
     *
     * @param clz
     * @param msg
     */
    fun info(clz: Class<*>?, msg: String) {
        if (TextUtils.isEmpty(LOG_TAG))
            throw IllegalArgumentException("LOG_TAG is null, please call init() method first")
        val clzName = clz?.simpleName ?: LogUtils::class.java.name
        i(LOG_TAG, "$clzName > $msg")
    }

    /**
     * 打印 Exception 日志
     *
     * @param clz
     * @param e
     */
    fun exception(clz: Class<*>?, e: Exception) {
        if (TextUtils.isEmpty(LOG_TAG))
            throw IllegalArgumentException("LOG_TAG is null, please call init() method first")
        val clzName = clz?.simpleName ?: LogUtils::class.java.name
        e(LOG_TAG, "$clzName > $e")
    }


}
